home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr30 / clockon.zip / CLOCKON.ASM next >
Assembly Source File  |  1993-05-07  |  26KB  |  708 lines

  1.         page    60,132
  2.         title   'CLOCKON'
  3.  
  4. ;mode    equ     0               ;mode = 0 for hh:mm only
  5. mode    equ     -1              ;mode = -1 for hh:mm:ss
  6.  
  7.         if      mode eq 0
  8. bytes           equ     5               ;bytes in hh:mm time display
  9. ticks           equ     36              ;ticks between clock updates
  10.         else
  11. bytes           equ     8               ;bytes in hh:mm:ss time display
  12. ticks           equ     18              ;ticks between clock updates
  13.         endif
  14. ;
  15. bel     equ     07H
  16. tab     equ     09H
  17. lf      equ     0aH
  18. cr      equ     0dH
  19. ;beta    equ     0e1H
  20. beta    equ     ' '
  21. ;
  22. ;****************************************************************
  23. ;
  24. ;++++   START OF RESIDENT CODE
  25. ;
  26. ;****************************************************************
  27. ;
  28. code    segment
  29.  
  30.         assume DS:code, SS:code ,CS:code ,ES:code
  31.  
  32.         org     0080H
  33.  
  34. dbuff   equ     $
  35.  
  36.         org     0100H
  37.  
  38. stack           equ     $
  39. start:
  40.         jmp     initialize
  41. ;
  42. inst_msg        db      'Clockon.HJH'   ;identifier message (leave it here!)
  43. msg_size        equ     $ - offset start
  44. ;
  45. colour          db      70h             ;predefined clock colours
  46. ;                                       ;lo nybble=F/G  hi nybble=B/G
  47. freq            dw      00600H          ;beep frequency
  48. beep_length     dw      40H             ;beep length (modified by CLOCKON x)
  49. ;
  50. max_alarms      equ     9               ;never more than 9 - may be less
  51. alarm_times     dw      max_alarms dup (0ffffH)  ;alarm times
  52. ;
  53. beep_count      equ     10              ;predefined beep count
  54. beeps           db      beep_count      ;set beep counter
  55. ;
  56. page_no         db      0               ;current page number
  57. no_display_flag db      '+'             ;'+' to enable, '-' to inhibit
  58. last_hour       dw      0               ;last hour - used to detect hour update
  59. old_cursor      dw      0               ;old cursor position
  60. ;
  61. ;
  62. line_col        equ     0050H - bytes   ;starting line and column for display
  63.  
  64. clk_count       dw      ticks           ;counts left to next update
  65. hours           dw      0               ;time ASCII store
  66.                 db      ':'
  67. minutes         dw      0
  68.                 db      ':'
  69. seconds         dw      0
  70. ;
  71. old_SP          dw      0               ;called SP
  72. old_SS          dw      0               ;called SS
  73. oldint08        dd      0               ;original INT 08 vector
  74. oldint10        dd      0               ;original INT 10 vector
  75. bios_flag       db      0               ;bios active flag
  76.  
  77. ;=============================================================================
  78. ; VIDINT intercepts and handles the video interrupt 10H.
  79. ;=============================================================================
  80.  
  81.         ASSUME  CS:code, DS:nothing
  82.  
  83. vidint  proc    near
  84.         pushf                           ;simulate INT
  85.         inc     CS:bios_flag            ;bump flag
  86.         call    CS:oldint10             ;call original function
  87.         dec     CS:bios_flag            ;decrement flag
  88.         iret
  89. vidint  endp
  90. ;
  91. ;----------------------------------------------------------------
  92. ;++++   Replaced INT 08  - used to detect when clock update needed
  93. ;
  94.         ASSUME  CS:code, DS:code
  95.  
  96. newint08        proc    near
  97.         push    ax                      ;save ax
  98.         push    DS                      ;and DS
  99.         pushf                           ;and flags
  100.         push    CS                      ;set up DS to point
  101.         pop     DS                      ;to CS
  102.         mov     ax,clk_count            ;get clock count
  103.         dec     ax                      ;decrement by 1
  104.         jz      int1                    ;skip if reaches zero
  105.         mov     clk_count,ax            ;new value saved
  106.         jmp     int8                    ;quick exit
  107. int1:
  108.         cli                             ;stop interrupts
  109.         mov     ax,SS                   ;save SS and SP
  110.         mov     old_SS,ax
  111.         mov     old_SP,sp
  112.         mov     ax,DS                   ;set SS to DS
  113.         mov     SS,ax
  114.         mov     sp,offset stack         ;and create a new stack
  115.         sti                             ;restart interrupts
  116.         push    bx                      ;save other regs
  117.         push    cx
  118.         push    dx
  119.         push    ES
  120.         push    si
  121.         push    di
  122.         push    bp
  123.         mov     ax,ticks                ;reset clock count
  124.         mov     clk_count,ax
  125. ;
  126. ;++++   Check for the time
  127. ;
  128.         mov     ah,0                    ;read clock count
  129.         int     1AH                     ;returns clock count in CX:DX
  130. ;
  131. ;++++   The following code takes the clock count returned by INT 1Ah
  132. ;       and:-
  133. ;       (1)     Multiplies by 16 by using repetitive shifts
  134. ;               (ignores overflow at the high end and inserts zeros
  135. ;               at the low end of DX:AX)
  136. ;       (2)     Divides by 17478 to convert to minutes
  137. ;               (17478 = 60 * 18.2065 * 16)
  138. ;
  139.         mov     ax,dx                   ;low time count to ax
  140.         mov     dx,cx                   ;hi  time count to dx
  141.         shl     ax,1                    ;multiply by 2
  142.         rcl     dx,1                    ;multiply by 2, add carry
  143.         shl     ax,1                    ;multiply by 2
  144.         rcl     dx,1                    ;multiply by 2, add carry
  145.         shl     ax,1                    ;multiply by 2
  146.         rcl     dx,1                    ;multiply by 2, add carry
  147.         shl     ax,1                    ;multiply by 2
  148.         rcl     dx,1                    ;multiply by 2, add carry
  149.         mov     bx,04446h
  150.         div     bx                      ;divide it by 17478
  151.                                         ;AX=minutes  DX=remainder
  152.         mov     cx,max_alarms           ;# alarms to test
  153.         xor     bx,bx                   ;start at first alarm
  154. alarm_loop:
  155.         call    alarm_test
  156.         jz      int3                    ;quick exit if alarm was sounded
  157.         add     bx,2
  158.         loop    alarm_loop
  159. int3:
  160.         call    display_check           ;see if display wanted
  161.         jc      int4                    ;continue if carry set
  162.         jmp     int7                    ;otherwise quick exit
  163. int4:
  164.         mov     seconds,dx              ;set seconds to dx
  165.         mov     bx,60                   ;divisor = 60
  166.         xor     dx,dx                   ;clear dx
  167.         div     bx
  168.         mov     minutes,dx              ;set minutes to dx
  169.         cmp     ax,0                    ;test ax
  170.         aam                             ;adjust
  171.         cmp     ax,last_hour            ;see if hour has changed
  172.         jz      int5
  173.         mov     last_hour,ax            ;update hour store
  174.         call    beep                    ;and beep once
  175. int5:
  176.         add     ax,'00'                 ;make hours into ASCII
  177.         xchg    ah,al
  178.         mov     hours,ax                ;save bytes
  179.         mov     ax,minutes              ;get minutes
  180.         aam                             ;adjust
  181.         add     ax,'00'
  182.         xchg    ah,al
  183.         mov     minutes,ax              ;and store
  184.         mov     ax,seconds              ;get seconds
  185.         xor     dx,dx
  186.         mov     bx,60
  187.         mul     bx
  188.         mov     bx,04446h
  189.         div     bx
  190.         aam                             ;adjust
  191.         add     ax,'00'
  192.         xchg    ah,al
  193.         mov     seconds,ax              ;and store
  194.         mov     ah,3
  195.         mov     bh,page_no              ;get page number
  196.         int     10H                     ;read cursor position
  197.         mov     old_cursor,dx
  198.         mov     ah,2
  199.         mov     bh,page_no              ;get page number
  200.         mov     dx,line_col             ;starting line/column
  201.         int     10H                     ;set cursor position
  202.         mov     si,offset hours         ;point to ASCII store
  203.         mov     bl,colour               ;colour select
  204.         mov     cx,bytes                ;bytes to send
  205. int6:
  206.         push    cx                      ;save count
  207.         mov     al,[si]                 ;get character
  208.         inc     si                      ;bump to next address
  209.         push    si                      ;save current pointer
  210.         mov     cx,1
  211.         mov     ah,9
  212.         int     10H                     ;write char with attribute
  213.         mov     ah,3
  214.         int     10H                     ;read cursor position
  215.         inc     dl                      ;bump by 1 column
  216.         mov     ah,2
  217.         int     10H                     ;set cursor position
  218.         pop     si                      ;recover current pointer
  219.         pop     cx                      ;recover count
  220.         loop    int6
  221.         mov     dx,old_cursor
  222.         mov     bh,page_no
  223.         mov     ah,2
  224.         int     10H                     ;reset old cursor position
  225. int7:
  226.         pop     bp                      ;restore registers
  227.         pop     di
  228.         pop     si
  229.         pop     ES
  230.         pop     dx
  231.         pop     cx
  232.         pop     bx
  233.         cli                             ;restore SP and SS
  234.         mov     ax,old_SS
  235.         mov     SS,ax
  236.         mov     sp,old_SP
  237.         sti
  238. int8:
  239.         popf                            ;recover flags
  240.         pop     DS                      ;and regs
  241.         pop     ax
  242.         jmp     dword ptr       CS:oldint08
  243. newint08        endp
  244. ;
  245. ;----------------------------------------------------------------
  246. ;++++   Test to see if display of clock wanted
  247. ;       Returns CARRY flag set if wanted
  248. ;
  249. display_check   proc    near
  250.         push    ax
  251.         push    bx
  252.         cmp     no_display_flag,'-'     ;test display flag
  253.         je      dc_off
  254.         cmp     bios_flag,0             ;in bios?
  255.         jne     dc_off                  ;not allowed if it is
  256. disp_1:
  257.         mov     ah,15                   ;get video mode
  258.         int     10H
  259.         mov     page_no,bh              ;save current page
  260.         cmp     al,2                    ;see if mode 2
  261.         je      dc_on
  262.         cmp     al,3                    ;or mode 3
  263.         je      dc_on
  264.         cmp     al,7                    ;or mode 7
  265.         je      dc_on
  266. dc_off:
  267.         pop     bx
  268.         pop     ax
  269.         clc
  270.         ret
  271. dc_on:
  272.         pop     bx
  273.         pop     ax
  274.         stc
  275.         ret
  276. display_check   endp
  277. ;
  278. ;----------------------------------------------------------------
  279. ;++++   Test for alarm pointed by bx
  280. ;
  281. alarm_test      proc    near
  282.         cmp     ax,alarm_times[bx]      ;compare result with alarm time
  283.         jne     alarm_test_2
  284.         push    ax                      ;save alarm time
  285.         call    dbl_beep                ;alarm double beep
  286.         mov     al,beeps                ;load beeps
  287.         dec     al                      ;decrement
  288.         mov     beeps,al                ;and save
  289.         cmp     al,0                    ;see if zero yet
  290.         jnz     alarm_test_1            ;skip if not
  291.         mov     beeps,beep_count
  292.         mov     ax,0FFFFh               ;reset alarm time to max
  293.         mov     alarm_times[bx],ax      ;to prevent retrigger
  294. alarm_test_1:
  295.         xor     ax,ax                   ;set zero flag
  296.         pop     ax                      ;recover current minutes
  297. alarm_test_2:
  298.         ret
  299. alarm_test      endp
  300. ;
  301. ;----------------------------------------------------------------
  302. ;++++   Produces double beep for alarm
  303. ;
  304. dbl_beep        proc    near
  305.         call    beep                    ;first beep
  306.         push    cx
  307.         mov     cx,beep_length          ;timeout loop
  308. dbl1:
  309.         dec     al
  310.         jnz     dbl1                    ;extra delay
  311.         loop    dbl1                    ;inter-beep delay
  312.         pop     cx
  313.         call    beep                    ;second beep
  314.         ret
  315. dbl_beep        endp
  316. ;
  317. ;----------------------------------------------------------------
  318. ;++++   Beep generator
  319. ;       Directly accesses sound generator timer in 8253
  320. ;
  321. beep    proc    near
  322.         push    ax
  323.         push    cx
  324.         mov     al,0B6H                 ;select timer #2
  325.         out     43H,al
  326.         mov     ax,freq                 ;pick up timer count
  327.         out     42H,al                  ;low byte
  328.         mov     al,ah
  329.         out     42H,al                  ;high byte
  330.         in      al,61H                  ;get control word
  331.         push    ax
  332.         or      al,3                    ;start timer
  333.         out     61H,al
  334.         mov     cx,beep_length          ;beep length constant
  335. beep1:
  336.         dec     al
  337.         jnz     beep1
  338.         loop    beep1                   ;time delay for ON
  339.         pop     ax
  340.         out     61H,al                  ;restore timer OFF
  341.         pop     cx
  342.         pop     ax
  343.         ret
  344. beep    endp
  345. ;
  346. ;----------------------------------------------------------------
  347. ;
  348. end_resident    equ     $
  349. ;
  350. ;****************************************************************
  351. ;
  352. ;++++   END OF RESIDENT CODE
  353. ;
  354. ;****************************************************************
  355.         page
  356. ;****************************************************************
  357. ;++++   Initialization code
  358. ;       Tests for already loaded code.
  359. ;       If not present, installs code first.
  360. ;       Then proceeds to decode command line.
  361. ;
  362. initialize      proc    near
  363.         not     word ptr start
  364.         xor     bx,bx
  365.         mov     ax,CS
  366. next_segment:
  367.         inc     bx
  368.         cmp     ax,bx
  369.         mov     ES,bx
  370.         jz      not_installed
  371.         mov     si,offset start
  372.         mov     di,si
  373.         mov     cx,msg_size
  374.         repz    cmpsb
  375.         or      cx,cx
  376.         jnz     next_segment
  377.         call    scan                    ;scan command line
  378.         mov     al,err_code             ;get error code
  379.         mov     ah,4cH
  380.         int     21H                     ;exit program
  381. ;
  382. not_installed:
  383.         mov     ax,3510H                ;save old interrupt 10H vector
  384.         int     21H
  385.         mov     word ptr oldint10,bx
  386.         mov     word ptr oldint10[2],es
  387.         mov     ax,2510H                ;then set the new 10H vector
  388.         mov     dx,offset vidint
  389.         int     21H
  390.         mov     ax,3508H                ;save old interrupt 08H vector
  391.         int     21H
  392.         mov     word ptr oldint08,bx
  393.         mov     word ptr oldint08[2],es
  394.         mov     ax,2508H                ;then set the new 08H vector
  395.         mov     dx,offset newint08
  396.         int     21H
  397.         push    CS                      ;make ES=CS
  398.         pop     ES
  399.         call    scan                    ;scan command line
  400.         mov     dx,offset msg7
  401.         call    print                   ;send message to advise now resident
  402.         mov     dx,offset end_resident  ;last address to save
  403.         mov     cl,4
  404.         shr     dx,cl                   ;make into pages
  405.         inc     dx                      ;plus 1
  406.         mov     al,err_code             ;get error code
  407.         mov     ah,31H
  408.         int     21H                     ;terminate but stay resident
  409. initialize      endp
  410. ;
  411. ;----------------------------------------------------------------
  412. ;++++   Scan command line starting at 0080h
  413. ;       Looks for control bytes and/or time code of form 'hh:mm'
  414. ;
  415. scan    proc    near
  416.         mov     alarms,0                ;alarms done count
  417.         xor     ax,ax                   ;AX=current minutes store
  418.         xor     bx,bx
  419.         xor     dx,dx                   ;DH=':' field counter
  420.         mov     di,0FFFFh               ;DI=minutes store
  421.         mov     ES:beeps,beep_count     ;preset beep counter
  422.         mov     si,offset dbuff         ;point to start of string area
  423.         mov     bl,[si]                 ;get string length byte
  424.         inc     si
  425.         mov     byte ptr [si+bx],al     ;end of string set to zero
  426. ;
  427. ;++++   Character scanner loop
  428. ;
  429. scan1:
  430.         call    getchar                 ;get a character
  431.         jnz     scan1a
  432.         jmp     all_done                ;exit if all done
  433. scan1a:
  434.         cmp     bl,' '                  ;test for space
  435.         jb      scan1                   ;skip over control characters
  436.         je      space_found             ;space found
  437.         cmp     bl,'?'                  ;test for '?' option
  438.         jne     scan1b
  439. ;
  440. ;++++   help message requested - ignore all other functions
  441. ;
  442.         mov     dx,offset helpmsg
  443.         call    print
  444.         ret
  445. ;
  446. ;++++   Test now for '-'
  447. ;
  448. scan1b:
  449.         cmp     bl,'-'                  ;test for '-' option
  450.         jne     scan1c                  ;skip if not
  451.         mov     ES:no_display_flag,bl   ;set up flag
  452.         jmp     short scan1
  453. ;
  454. ;++++   Test now for '+'
  455. ;
  456. scan1c:
  457.         cmp     bl,'+'                  ;test for '+' option
  458.         jne     scan1d                  ;skip if not
  459.         mov     ES:no_display_flag,bl   ;set up flag
  460.         jmp     short scan1
  461. ;
  462. ;++++   Test now for 'x'
  463. ;
  464. scan1d:
  465.         cmp     bl,'X'                  ;test for 'x' option
  466.         jne     scan1e                  ;skip if not
  467.         push    ax
  468.         mov     ax,ES:beep_length       ;get beep length
  469.         shr     ax,1                    ;halve it
  470.         add     ES:beep_length,ax       ;beep length time increased 50%
  471.         pop     ax
  472.         jmp     short scan1
  473. ;
  474. ;++++   Test now for '*'
  475. ;
  476. scan1e:
  477.         cmp     bl,'*'                  ;test for '*' option
  478.         jne     scan2                   ;skip if not
  479.         mov     alarms,0                ;alarms done count
  480.         xor     ax,ax                   ;AX=current minutes store
  481.         xor     bx,bx
  482.         xor     dx,dx                   ;DH=':' field counter
  483.         mov     di,0FFFFh               ;DI=minutes store
  484.         mov     cx,max_alarms
  485. clear_1:
  486.         mov     ES:alarm_times[bx],di   ;clear alarm minutes store
  487.         add     bx,2                    ;next store
  488.         loop    clear_1
  489.         jmp     short scan1
  490. ;
  491. ;++++   Test now for ':' time delimiter
  492. ;
  493. scan2:
  494.         cmp     bl,':'                  ;test for separator
  495.         jnz     scan3                   ;skip if not
  496.         inc     dh                      ;bump field count
  497.         cmp     dh,2                    ;see if 2 ':' chars received
  498.         jae     time_1                  ;error if found
  499.         push    dx
  500.         mov     cx,60                   ;multiply hours by 60
  501.         mul     cx
  502.         pop     dx                      ;recover regs
  503.         mov     di,ax                   ;save hours*60
  504.         mov     ax,0                    ;clear counter again
  505.         jmp     short scan4
  506. space_found:
  507.         cmp     di,0ffffH               ;see if anything done yet
  508.         je      time_5                  ;skip if not
  509.         cmp     dh,1                    ;see if timer was being processed
  510.         jne     time_1
  511.         add     ax,di                   ;add minutes to count
  512.         cmp     ax,1440                 ;see if overflow
  513.         jb      time_2
  514. time_1:
  515.         mov     dx,offset msg1          ;error message
  516.         mov     err_code,2
  517.         jmp     time_msg
  518. time_2:
  519.         mov     bx,alarms               ;get current alarms
  520.         cmp     bx,max_alarms           ;see if too many
  521.         jb      time_3
  522.         mov     dx,offset msg4          ;too many alarms
  523.         mov     err_code,1
  524.         jmp     time_msg
  525. time_3:
  526.         add     bx,bx                   ;make count into pointer
  527.         cmp     ES:alarm_times[bx],0FFFFh       ;see if free
  528.         je      time_4
  529.         inc     alarms                  ;bump alarms count
  530.         jmp     time_2
  531. time_4:
  532.         mov     ES:alarm_times[bx],ax   ;save alarm minutes count
  533.         inc     alarms                  ;update alarms counter
  534. time_5:
  535.         xor     ax,ax                   ;clear running sum
  536.         mov     di,0ffffH               ;initialize minutes counter
  537.         xor     dx,dx                   ;clear ':' conter
  538.         jmp     scan1                   ;try next count
  539. ;
  540. ;++++   Must be 0-9 or else will be ignored
  541. ;
  542. scan3:
  543.         cmp     bl,'0'                  ;test for ASCII '0'-'9'
  544.         jb      bad_char
  545.         cmp     bl,'9'
  546.         ja      bad_char
  547.         sub     bl,'0'                  ;make into binary digit
  548.         push    dx
  549.         mov     cx,10
  550.         mul     cx                      ;multiply running sum by 10
  551.         add     ax,bx                   ;add in new digit
  552.         pop     dx
  553.         cmp     ax,59                   ;see if overflow
  554.         ja      time_1                  ;out of range
  555. scan4:
  556.         jmp     scan1                   ;loop for next char
  557. bad_char:
  558.         mov     dx,offset msg5
  559.         mov     err_code,3
  560.         jmp     time_msg
  561. ;
  562. ;++++   scan complete
  563. ;
  564. all_done:
  565.         cmp     di,0ffffH               ;see if new time specified
  566.         je      scan7                   ;skip if not
  567.         dec     si                      ;back up over EOT byte
  568.         jmp     space_found             ;process data as though delimiter
  569. ;
  570. time_msg:
  571.         call    print                   ;print error message
  572. scan7:
  573.         mov     dx,offset msg6          ;assume display is set
  574.         cmp     ES:no_display_flag,'-'  ;test for no display
  575.         jne     scan8
  576.         mov     dx,offset msg3          ;print message
  577. scan8:
  578.         call    print
  579.         call    show_times              ;show times
  580.         ret                             ;return
  581. scan    endp
  582. ;
  583. ;----------------------------------------------------------------
  584. ;++++   Get character from input buffer
  585. ;++++   Convert to upper case if necessary
  586. ;       Place in BL and set zero flag if BL=0
  587. ;
  588. getchar proc    near
  589.         mov     bl,[si]                 ;get character
  590.         inc     si                      ;bump string pointer
  591.         cmp     bl,'a'                  ;below 'a' test
  592.         jb      getchar_1
  593.         cmp     bl,'z'                  ;above 'z' test
  594.         ja      getchar_1
  595.         sub     bl,20h                  ;make Upper Case
  596. getchar_1:
  597.         or      bl,bl                   ;test for zero
  598.         ret
  599. getchar endp
  600. ;
  601. ;----------------------------------------------------------------
  602. ;++++   send character to CON:
  603. ;
  604. charout proc    near
  605.         push    ax              ;save ax
  606.         mov     ah,2            ;set up command
  607.         int     21H             ;send character in DL
  608.         pop     ax              ;recover ax
  609.         ret
  610. charout endp
  611. ;
  612. ;----------------------------------------------------------------
  613. ;++++   Print string to user
  614. ;
  615. print   proc    near
  616.         push    ax              ;save ax
  617.         mov     ah,9            ;set up command
  618.         int     21H             ;print string ending with '$'
  619.         pop     ax              ;recover ax
  620.         ret
  621. print   endp
  622. ;
  623. ;----------------------------------------------------------------
  624. ;
  625. show_times      proc    near
  626.         mov     cx,max_alarms           ;maximum alarms allowed
  627.         mov     bx,0                    ;start at first alarm
  628.         mov     msg2,'0'
  629. show_time_1:
  630.         mov     ax,ES:alarm_times[bx]   ;get alarm time
  631.         cmp     ax,0FFFFh               ;see if cleared
  632.         je      show_time_5
  633.         inc     msg2                    ;bump alarm counter
  634.         mov     dx,0                    ;hi word zero
  635.         div     div60                   ;convert to hh:mm
  636.         push    dx                      ;save remainder (minutes)
  637.         call    show_number             ;show hours
  638.         mov     dl,':'
  639.         call    charout
  640.         pop     ax
  641.         call    show_number             ;show minutes
  642.         mov     dl,' '
  643.         call    charout                 ;couple of spaces
  644.         call    charout
  645. show_time_5:
  646.         add     bx,2                    ;bump pointer
  647.         loop    show_time_1
  648.         call    crlf
  649.         mov     dx,offset msg2          ;total alarms set
  650.         call    print
  651.         ret
  652. div60   dw      60
  653. show_times      endp
  654. ;
  655. ;----------------------------------------------------------------
  656. ;++++   display number in AL as two decimal digits
  657. ;
  658. show_number     proc    near
  659.         xor     ah,ah                   ;clear hi byte
  660.         div     div10                   ;divide by 10
  661.         add     ax,'00'                 ;make ASCII
  662.         push    ax                      ;save result
  663.         mov     dl,al
  664.         call    charout                 ;print 10s digit
  665.         pop     ax
  666.         mov     dl,ah
  667.         call    charout                 ;print 1s digit
  668.         ret
  669. div10   db      10
  670. show_number     endp
  671. ;
  672. ;----------------------------------------------------------------
  673. ;++++   Send CRLF to console
  674. ;
  675. crlf    proc    near
  676.         push    dx
  677.         mov     dl,CR
  678.         call    charout
  679.         mov     dl,LF
  680.         call    charout
  681.         pop     dx
  682.         ret
  683. crlf    endp
  684. ;
  685. ;----------------------------------------------------------------
  686. ;
  687. err_code        db      0               ;error code for DOS return
  688. alarms          dw      0               ;current alarm counter
  689. ;
  690. helpmsg db      CR,LF,'******* CLOCKON V2.01e',BETA,'*******',CR,LF
  691.         db      'Command format is CLOCKON [+|-] [x] [*] [hh:mm .... ]',CR,LF
  692.         db      TAB,'where   +   enables  clock display',CR,LF
  693.         db      TAB,'        -   inhibits clock display',CR,LF
  694.         db      TAB,'        x   extends  alarm sounds',CR,LF
  695.         db      TAB,'        *   clears all current alarms',CR,LF
  696.         db      TAB,'      hh:mm sets alarm times (up to 9)',CR,LF,'$'
  697. msg1    db      bel,'ERROR: Invalid time. Range is 00:00 to 23:59',CR,LF,'$'
  698. msg2    db      '0 alarm(s) set.',CR,LF,'$'
  699. msg3    db      'Clock display is inhibited.',CR,LF,'$'
  700. msg6    db      'Clock display is enabled.',CR,LF,'$'
  701. msg4    db      bel,'WARNING: Only 9 alarms allowed.',CR,LF,'$'
  702. msg5    db      bel,'ERROR: Illegal character in command.',CR,LF,'$'
  703. msg7    db      'CLOCKON is now resident.',CR,LF,'$'
  704. code    ends
  705. ;
  706.         end     start
  707.  
  708.